package mspbots.next.ticket.core.data.tickets;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.next.ticket.common.QueryParams;
import mspbots.next.ticket.common.RequestApiParams;
import mspbots.next.ticket.core.client.WiseClient;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * spots.next.ticket.core.data.TicketsServiceImpl
 *
 * @author <a href="https://github.com/vnobo">Alex bob</a>
 * @date Created by 2020/12/1
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class TicketsServiceImpl {

    private final WiseClient wiseClient;
    private final TicketsProperties ticketsProperties;

    public Flux<JsonNode> fetch(Long tenantId, QueryParams queryParams) {
        return this.count(tenantId, queryParams)
                .map(jsonNode -> jsonNode.get("count").asLong(0L))
                .filter(count -> count > 0)
                .flatMapMany(r -> this.getTickets(tenantId, queryParams));
    }

    public Flux<JsonNode> getTickets(Long tenantId, QueryParams queryParams) {
        return this.wiseClient.fetch(RequestApiParams.withDefault(tenantId)
                .queryParams(queryParams).request("/tickets/{tenantId}/find"))
                .onErrorResume(err -> {
                    log.error("Get service ticket is error, msg: {}", err.getMessage());
                    return Mono.empty();
                })
                .mergeWith(this.wiseClient.fetch(RequestApiParams.withDefault(tenantId)
                        .queryParams(queryParams).request("/tickets/{tenantId}/project/find"))
                        .onErrorResume(err -> {
                            log.error("Get project ticket is error, msg: {}", err.getMessage());
                            return Mono.empty();
                        }))
                .limitRate(ticketsProperties.getLimitRate().getHighTide(), ticketsProperties.getLimitRate().getLowTide())
                .limitRequest(ticketsProperties.getLimitRequest());
    }

    private Mono<JsonNode> count(Long tenantId, QueryParams queryParams) {
        return this.wiseClient.get("/tickets/{tenantId}/count", queryParams, Map.of("tenantId", tenantId));
    }
}
